package com.example.ec.dao.impl;

import com.example.ec.dao.GenericDao;
import com.example.ec.util.Pagination;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

public class GenericDaoImpl<T extends Serializable, ID extends Number> implements GenericDao<T, ID> {

    private SqlSession sqlSession;

    @Autowired
    public void setSqlSession(SqlSession sqlSession) {
        this.sqlSession = sqlSession;
    }

    private final String namespace;

    @SuppressWarnings("unchecked")
    GenericDaoImpl() {
        ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
        Class<T> clazz = (Class<T>) parameterizedType.getActualTypeArguments()[0];
        this.namespace = StringUtils.uncapitalize(clazz.getSimpleName());
    }

    private String getStatement(String sqlId) {
        return this.namespace.concat(".").concat(sqlId);
    }

    @Override
    public void create(T t) {
        sqlSession.insert(getStatement("create"), t);
    }

    @Override
    public void removeById(ID id) {
        sqlSession.delete(getStatement("removeById"), id);
    }

    @Override
    public void modify(T t) {
        sqlSession.update(getStatement("modify"), t);
    }

    @Override
    public T queryById(ID id) {
        return sqlSession.selectOne(getStatement("queryById"), id);
    }

    @Override
    public List<T> queryAll() {
        return sqlSession.selectList(getStatement("queryAll"));
    }

    @Override
    public void create(String sqlId, Object parameter) {
        sqlSession.insert(getStatement(sqlId), parameter);
    }

    @Override
    public void modify(String sqlId, Object parameter) {
        sqlSession.insert(getStatement(sqlId), parameter);

    }

    @Override
    public T queryOne(String sqlId, Object parameter) {
        return sqlSession.selectOne(getStatement(sqlId), parameter);
    }

    @Override
    public List<T> queryList(String sqlId, Object parameter) {
        return sqlSession.selectList(getStatement(sqlId), parameter);
    }

    @Override
    public Object query(String sqlId, Object parameter) {
        return sqlSession.selectOne(getStatement(sqlId), parameter);
    }

    @Override
    public Pagination<T> queryAll(int currentPage) {
        return getPagination("queryAll", null, currentPage);
    }

    @Override
    public Pagination<T> query(String sqlId, Object parameter, int currentPage) {
        return getPagination(sqlId, parameter, currentPage);
    }

//    分页功能实现
    private Pagination<T> getPagination(String sqlId, Object parameter, int currentPage) {
//      总的数据条数
        int totalRows = sqlSession.selectList(getStatement(sqlId), parameter).size();
//      数据分页的页数
        int pageSize = 5;
//      （每页记录的条数）除法中是会舍弃余数 需要保留余数并且将余出来的数据转到下一页
        int totalPages = (int) Math.ceil(totalRows / (double) pageSize);
//
        RowBounds rowBounds = new RowBounds(pageSize * (currentPage - 1), pageSize);
        List<T> list = sqlSession.selectList(getStatement(sqlId), parameter, rowBounds);
        return new Pagination<>(sqlId, list, totalRows, pageSize, totalPages, currentPage);
    }
}

